﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;

namespace KataBankOCR
{
    /// <summary>
    /// Class to read in a file of account numbers, each account number is in digit lines (number defined in Digit.numLines) and 
    /// then a blank line (a line with only a newline char)
    /// </summary>
    class ScannedFile
    {
        private string filename;
        private StreamReader fileReader;


        public string Filename
        {
            get { return filename; }
        }

        ~ScannedFile()
        {
            close();
        }

        /// <summary>
        /// Read account number lines from file
        /// </summary>
        /// <returns>Array of strings for a digit or Null if at end of file</returns>
        public string[] nextAccountNumber()
        {
            string currentLine;
            Queue lineQ = new Queue(Digit.numLines);

            // read file until get required digit lines followed by a blank line, or until end of file
            while ((currentLine = fileReader.ReadLine()) != null)
            {
                if (lineQ.Count == Digit.numLines)
                {
                    if (currentLine.Length == 0)
                    {
                        // have a blank line and the needed number of lines to return them so exit loop
                        break;
                    }
                    else
                    {
                        // have non-blank line 
                        // keep only number of last non-blank lines that are in a digit
                        // drop oldest line
                        string eatit = (string)lineQ.Dequeue();
                        // add the new non-blank line
                        lineQ.Enqueue(currentLine);
                    }
                }
                else
                {
                    if (currentLine.Length == 0)
                    {
                        // found blank before the needed number of lines so clear queue
                        lineQ = new Queue(Digit.numLines);
                    }
                    else
                    {
                        // save non-blank line
                        lineQ.Enqueue(currentLine);
                    }
                }
            }

            // return strings if got need number of non-blank lines. (works even if last blank line is missing)
            if (lineQ.Count == Digit.numLines)
            {
                // return queued lines as string array
                string[] digitStrings = new string[Digit.numLines];
                for (int lineIndex = 0; lineIndex < Digit.numLines; lineIndex++)
                {
                    digitStrings[lineIndex] = (string) lineQ.Dequeue();
                }
                return digitStrings;
            }
            else
            {
                // return null since at end of file 
                return null;
            }

        }

        /// <summary>
        /// Open filename specified and return first line
        /// </summary>
        /// <param name="fileToRead">Name of file to read</param>
        /// <returns>First line of file or null if End Of File</returns>
        public string[] firstAccountNumber(string fileToRead)
        {
            filename = fileToRead;
            fileReader = new System.IO.StreamReader(filename);
            return nextAccountNumber();
        }

        /// <summary>
        /// Close file if it is open, ignoring any error. So no error if file not defined or not open
        /// </summary>
        public void close()
        {
            try 
        	{	        
                // try to close file if not already
		        fileReader.Close();
	        }
        	catch (Exception)
	        {
                //Ignore and exceptions
	        }
        }
    }
}
